package com.sddnytsh.body_buildingsystem.network

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.sddnytsh.body_buildingsystem.config.NetworkConfig
import com.sddnytsh.body_buildingsystem.topic.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.util.concurrent.TimeUnit

/**
 * 运动记录API服务类
 * 处理与fitness-send的HTTP通信
 */
class ExerciseApiService {
    
    private val client = OkHttpClient.Builder()
        .connectTimeout(5, TimeUnit.SECONDS)
        .readTimeout(8, TimeUnit.SECONDS)
        .writeTimeout(5, TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
        .build()
    
    private val gson = Gson()
    
    /**
     * 格式化时长（秒数转换为HH:MM:SS格式）
     */
    private fun formatDuration(seconds: Number?): String {
        if (seconds == null) return "00:00:00"
        val totalSeconds = seconds.toLong()
        val hours = totalSeconds / 3600
        val minutes = (totalSeconds % 3600) / 60
        val secs = totalSeconds % 60
        return String.format("%02d:%02d:%02d", hours, minutes, secs)
    }
    
    /**
     * 获取所有运动信息
     */
    suspend fun getAllExercises(): Result<List<ExerciseInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-info")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "获取所有运动API返回的data: $data")
                    // 根据后端逻辑，exercises在data.exerciseInfos中
                    val exercises = data?.get("exerciseInfos") as? List<*>
                    val exerciseList = exercises?.map { exerciseData ->
                        val exerciseMap = exerciseData as Map<*, *>
                        ExerciseInfo(
                            id = (exerciseMap["id"] as? Number)?.toLong() ?: 0L,
                            name = exerciseMap["name"] as? String ?: "",
                            category = exerciseMap["category"] as? String ?: "",
                            description = exerciseMap["description"] as? String ?: "",
                            hasSpeed = exerciseMap["hasSpeed"] as? Boolean ?: false,
                            hasHeartRate = exerciseMap["hasHeartRate"] as? Boolean ?: false,
                            createdAt = exerciseMap["createdAt"] as? String ?: "",
                            updatedAt = exerciseMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的运动列表大小: ${exerciseList.size}")
                    Result.success(exerciseList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取运动信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 根据分类获取运动信息
     */
    suspend fun getExercisesByCategory(category: String): Result<List<ExerciseInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-info/category/$category")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "获取分类运动API返回的data: $data")
                    // 根据后端逻辑，exercises在data.exerciseInfos中
                    val exercises = data?.get("exerciseInfos") as? List<*>
                    val exerciseList = exercises?.map { exerciseData ->
                        val exerciseMap = exerciseData as Map<*, *>
                        ExerciseInfo(
                            id = (exerciseMap["id"] as? Number)?.toLong() ?: 0L,
                            name = exerciseMap["name"] as? String ?: "",
                            category = exerciseMap["category"] as? String ?: "",
                            description = exerciseMap["description"] as? String ?: "",
                            hasSpeed = exerciseMap["hasSpeed"] as? Boolean ?: false,
                            hasHeartRate = exerciseMap["hasHeartRate"] as? Boolean ?: false,
                            createdAt = exerciseMap["createdAt"] as? String ?: "",
                            updatedAt = exerciseMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的分类运动列表大小: ${exerciseList.size}")
                    Result.success(exerciseList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取分类运动信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 搜索运动信息
     */
    suspend fun searchExercises(keyword: String): Result<List<ExerciseInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-info/search?keyword=$keyword")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "搜索运动API返回的data: $data")
                    // 根据后端逻辑，exercises在data.exerciseInfos中
                    val exercises = data?.get("exerciseInfos") as? List<*>
                    val exerciseList = exercises?.map { exerciseData ->
                        val exerciseMap = exerciseData as Map<*, *>
                        ExerciseInfo(
                            id = (exerciseMap["id"] as? Number)?.toLong() ?: 0L,
                            name = exerciseMap["name"] as? String ?: "",
                            category = exerciseMap["category"] as? String ?: "",
                            description = exerciseMap["description"] as? String ?: "",
                            hasSpeed = exerciseMap["hasSpeed"] as? Boolean ?: false,
                            hasHeartRate = exerciseMap["hasHeartRate"] as? Boolean ?: false,
                            createdAt = exerciseMap["createdAt"] as? String ?: "",
                            updatedAt = exerciseMap["updatedAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的搜索运动列表大小: ${exerciseList.size}")
                    Result.success(exerciseList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "搜索运动信息失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 开始运动
     */
    suspend fun startExercise(exerciseRecord: ExerciseRecordStartRequest): Result<ExerciseRecordInfo> = withContext(Dispatchers.IO) {
        try {
            val requestBody = gson.toJson(exerciseRecord).toRequestBody("application/json".toMediaType())
            
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-records/start")
                .post(requestBody)
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    // 后端返回的data直接包含运动记录信息
                    val record = ExerciseRecordInfo(
                        id = (data?.get("id") as? Number)?.toLong() ?: 0L,
                        userId = (data?.get("userId") as? Number)?.toLong() ?: 0L,
                        exerciseId = (data?.get("exerciseId") as? Number)?.toLong() ?: 0L,
                        exerciseName = data?.get("exerciseName") as? String ?: "",
                        startTime = data?.get("startTime") as? String ?: "",
                        status = data?.get("status") as? String ?: "",
                        hasSpeed = false, // 需要从运动信息中获取
                        hasHeartRate = false, // 需要从运动信息中获取
                        createdAt = data?.get("createdAt") as? String ?: ""
                    )
                    Result.success(record)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "开始运动失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 结束运动
     */
    suspend fun endExercise(recordId: Long, endData: ExerciseRecordEndRequest): Result<ExerciseRecordInfo> = withContext(Dispatchers.IO) {
        try {
            val requestBody = gson.toJson(endData).toRequestBody("application/json".toMediaType())
            
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-records/$recordId/end")
                .post(requestBody)
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    // 后端返回的data直接包含运动记录信息
                    val record = ExerciseRecordInfo(
                        id = (data?.get("id") as? Number)?.toLong() ?: 0L,
                        userId = (data?.get("userId") as? Number)?.toLong() ?: 0L,
                        exerciseId = (data?.get("exerciseId") as? Number)?.toLong() ?: 0L,
                        exerciseName = data?.get("exerciseName") as? String ?: "",
                        startTime = data?.get("startTime") as? String ?: "",
                        endTime = data?.get("endTime") as? String ?: "",
                        duration = data?.get("duration") as? String ?: "",
                        durationSeconds = (data?.get("durationSeconds") as? Number)?.toLong() ?: 0L,
                        avgHeartRate = (data?.get("avgHeartRate") as? Number)?.toDouble(),
                        maxHeartRate = (data?.get("maxHeartRate") as? Number)?.toDouble(),
                        avgSpeed = (data?.get("avgSpeed") as? Number)?.toDouble(),
                        maxSpeed = (data?.get("maxSpeed") as? Number)?.toDouble(),
                        status = data?.get("status") as? String ?: "",
                        hasSpeed = data?.get("hasSpeed") as? Boolean ?: false,
                        hasHeartRate = data?.get("hasHeartRate") as? Boolean ?: false,
                        createdAt = data?.get("createdAt") as? String ?: ""
                    )
                    Result.success(record)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "结束运动失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 获取用户的所有运动记录
     */
    suspend fun getExerciseRecordsByUserId(userId: Long): Result<List<ExerciseRecordInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-records/user/$userId")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            android.util.Log.d("ExerciseApiService", "获取运动记录请求: userId=$userId")
            android.util.Log.d("ExerciseApiService", "获取运动记录响应: code=${response.code}, body=$responseBody")
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "获取运动记录API返回的data: $data")
                    // 根据后端逻辑，records在data.records中
                    val records = data?.get("records") as? List<*>
                    val recordList = records?.map { recordData ->
                        val recordMap = recordData as Map<*, *>
                        ExerciseRecordInfo(
                            id = (recordMap["id"] as? Number)?.toLong() ?: 0L,
                            userId = (recordMap["userId"] as? Number)?.toLong() ?: 0L,
                            exerciseId = (recordMap["exerciseId"] as? Number)?.toLong() ?: 0L,
                            exerciseName = recordMap["exerciseName"] as? String ?: "",
                            startTime = recordMap["startTime"] as? String ?: "",
                            endTime = recordMap["endTime"] as? String ?: "",
                            duration = formatDuration(recordMap["durationSeconds"] as? Number),
                            durationSeconds = (recordMap["durationSeconds"] as? Number)?.toLong() ?: 0L,
                            avgHeartRate = (recordMap["avgHeartRate"] as? Number)?.toDouble(),
                            maxHeartRate = (recordMap["maxHeartRate"] as? Number)?.toDouble(),
                            avgSpeed = (recordMap["avgSpeed"] as? Number)?.toDouble(),
                            maxSpeed = (recordMap["maxSpeed"] as? Number)?.toDouble(),
                            status = recordMap["status"] as? String ?: "",
                            hasSpeed = recordMap["hasSpeed"] as? Boolean ?: false,
                            hasHeartRate = recordMap["hasHeartRate"] as? Boolean ?: false,
                            createdAt = recordMap["createdAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的运动记录列表大小: ${recordList.size}")
                    Result.success(recordList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取运动记录失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            android.util.Log.e("ExerciseApiService", "获取运动记录异常", e)
            Result.failure(e)
        }
    }
    
    /**
     * 获取用户指定状态的运动记录
     */
    suspend fun getExerciseRecordsByUserIdAndStatus(userId: Long, status: String): Result<List<ExerciseRecordInfo>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-records/user/$userId/status/$status")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "获取状态运动记录API返回的data: $data")
                    // 根据后端逻辑，records在data.records中
                    val records = data?.get("records") as? List<*>
                    val recordList = records?.map { recordData ->
                        val recordMap = recordData as Map<*, *>
                        ExerciseRecordInfo(
                            id = (recordMap["id"] as? Number)?.toLong() ?: 0L,
                            userId = (recordMap["userId"] as? Number)?.toLong() ?: 0L,
                            exerciseId = (recordMap["exerciseId"] as? Number)?.toLong() ?: 0L,
                            exerciseName = recordMap["exerciseName"] as? String ?: "",
                            startTime = recordMap["startTime"] as? String ?: "",
                            endTime = recordMap["endTime"] as? String ?: "",
                            duration = formatDuration(recordMap["durationSeconds"] as? Number),
                            durationSeconds = (recordMap["durationSeconds"] as? Number)?.toLong() ?: 0L,
                            avgHeartRate = (recordMap["avgHeartRate"] as? Number)?.toDouble(),
                            maxHeartRate = (recordMap["maxHeartRate"] as? Number)?.toDouble(),
                            avgSpeed = (recordMap["avgSpeed"] as? Number)?.toDouble(),
                            maxSpeed = (recordMap["maxSpeed"] as? Number)?.toDouble(),
                            status = recordMap["status"] as? String ?: "",
                            hasSpeed = recordMap["hasSpeed"] as? Boolean ?: false,
                            hasHeartRate = recordMap["hasHeartRate"] as? Boolean ?: false,
                            createdAt = recordMap["createdAt"] as? String ?: ""
                        )
                    } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的状态运动记录列表大小: ${recordList.size}")
                    Result.success(recordList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取运动记录失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 获取运动分类
     */
    suspend fun getExerciseCategories(): Result<List<String>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/exercise-info/categories")
                .get()
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            val responseBody = response.body?.string() ?: ""
            
            android.util.Log.d("ExerciseApiService", "获取运动分类请求: ${request.url}")
            android.util.Log.d("ExerciseApiService", "获取运动分类响应: code=${response.code}, body=$responseBody")
            
            if (response.isSuccessful) {
                val type = object : TypeToken<ApiResponse<Map<String, Any>>>() {}.type
                val apiResponse = gson.fromJson<ApiResponse<Map<String, Any>>>(responseBody, type)
                
                if (apiResponse.success) {
                    val data = apiResponse.data
                    android.util.Log.d("ExerciseApiService", "运动分类API返回的data: $data")
                    // 根据后端逻辑，categories在data.categories中
                    val categories = data?.get("categories") as? List<*>
                    val categoryList = categories?.map { it.toString() } ?: emptyList()
                    android.util.Log.d("ExerciseApiService", "解析出的分类列表: $categoryList")
                    Result.success(categoryList)
                } else {
                    Result.failure(Exception(apiResponse.message ?: "获取运动分类失败"))
                }
            } else {
                Result.failure(Exception("请求失败: ${response.code}"))
            }
        } catch (e: Exception) {
            android.util.Log.e("ExerciseApiService", "获取运动分类异常", e)
            Result.failure(e)
        }
    }
}
